import datetime
import urllib.parse
from typing import List

import tornado.ioloop
from tornado.httputil import HTTPFile
from tornado_request_mapping import request_mapping

from base_web import HttpBasicHandler
from common.user_constant import UserConstant
from handler.http_handler.user_manage import active_sessions
from header.pm_header import PMHeader
from services.file_parse_service import ExcelFileParseService
from services.sql_service.mes_service import MesService
from services.sql_service.production_service import ProductionService
from services.sql_service.user_service import UserService
from tasks.ws_scheduler_task import WsSchedulerTask


@request_mapping('/product_manage')
class ProductManageHandler(HttpBasicHandler):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.mes_service = MesService()
        self.user_service = UserService()
        self.production_service = ProductionService()
        self.excel_service = ExcelFileParseService()
        self.web_socket_task = WsSchedulerTask()

    @request_mapping('/issue_order_by_excel', 'post', 'excel导入下发工单')
    async def issue_order_by_excel(self):
        session_id = self.get_cookie("session_id")
        user_id = active_sessions.get(session_id, None)
        if user_id:
            files: List[HTTPFile] = self.request.files.get('file')
            user = await self.user_service.find_user_by_id(user_id)
            if not user:
                return self.send_response_data('fail', '', '当前登录用户不存在')
            if user['level'] != UserConstant.engineer:
                return self.send_response_data('fail', '', '仅工程师等级用户有下发工单权限')
            if not files:
                return self.send_response_data('fail', '', '上传excel文件为空')
            file = files[0]
            await self.excel_service.insert_data_to_excel(file)
            # 下发后立即调用发送bom数据部分的ws
            tornado.ioloop.IOLoop.current().spawn_callback(self.web_socket_task.send_bom)
            return self.send_response_data('success', '', '下发成功')
        return self.send_response_data('fail', '', '请先登录')

    @request_mapping('/issue_order', 'post', '下发工单.传列表[{},{}]')
    async def issue_order(self):
        """
        {"user_id":"1",
        "data100":"A20240510",
        "data101":"SD075-PN",
        "data102":"5",
        "data103":"ZC10312",
        "data104":"2",
        "data105":"ZCZ10312",
        "data106":"1",
        "data107":"DG203-1",
        "data108":"1",
        "data109":"LJB221-A",
        "data110":"1",
        "data111":"4",
        "is_export":false,
        "file":""}
        :return:
        """
        data = self.data
        session_id = self.get_cookie("session_id")
        user_id = active_sessions.get(session_id, None)
        if user_id:
            user = await self.user_service.find_user_by_id(user_id)
            if not user:
                return self.send_response_data('fail', '', '当前登录用户不存在')
            if user['level'] != UserConstant.engineer:
                return self.send_response_data('fail', '', '仅工程师等级用户有下发工单权限')
            cur_time_str = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            data['data112'] = cur_time_str
            sorted_data_tuple = tuple([data.get(key) for key in PMHeader.sorted_field])
            await self.mes_service.insert_issue_order(sorted_data_tuple)
            # 下发后立即调用发送bom数据部分的ws
            tornado.ioloop.IOLoop.current().spawn_callback(self.web_socket_task.send_bom)
            return self.send_response_data('success', '', '下发成功')
        return self.send_response_data('fail', '', '请先登录')

    @request_mapping('/template_download', 'get', '下发工单下载模版')
    async def template_download(self):
        bom_header = PMHeader.bom_header
        name_header = [i['name'] for i in bom_header][:-2]
        filename = '工单下发模板.xlsx'
        buffer = await self.excel_service.template_download(name_header)
        r = buffer.read()
        # 设置响应头并返回文件
        self.set_header('Content-Type', 'application/octet-stream')
        self.set_header('Content-Disposition', 'attachment; filename=%s; filename*=%s' %
                        (urllib.parse.quote(filename), urllib.parse.quote(filename)))
        self.write(r)
        await self.finish()
        buffer.close()

    @request_mapping('/issue_header', 'get', '获取下发工单的头部')
    async def get_issue_order_header(self):
        bom_header = PMHeader.bom_header
        issue_header = bom_header[:-2]
        return self.send_response_data('success', issue_header, 'ok')

    @request_mapping('/production_query', 'get', '生产查询:序列号查询、时间区间查询')
    async def production_query(self):
        """
        :param {'serial_number':"11111,
        'start_time':"",end_time}
        :return:
        """
        data = self.data
        pack_data = await self.production_service.production_query(data)

        if not data.get('is_export'):
            return self.send_response_data('success', pack_data, 'ok')
        # 导出
        filename = '生产查询导出.xlsx'
        buffer = await self.excel_service.export_data_to_excel(pack_data)
        r = buffer.read()
        with open('test.xlsx', 'wb') as wf:
            wf.write(r)
        # 设置响应头并返回文件
        self.set_header('Content-Type', 'application/octet-stream')
        self.set_header('Content-Disposition', 'attachment; filename=%s; filename*=%s' %
                        (urllib.parse.quote(filename), urllib.parse.quote(filename)))
        self.write(r)
        await self.finish()
        buffer.close()
